import os
import json
import requests
from bs4 import BeautifulSoup
import re
import time
import numpy as np
import pandas as pd

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


def get_html(code, start_date, end_date, page=1, per=20):
    url = 'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={0}&page={1}&sdate={2}&edate={3}&per={4}'.format(
        code, page, start_date, end_date, per)
    rsp = requests.get(url)
    html = rsp.text
    return html


def get_fund(code, start_date, end_date, page=1, per=20):
    # 获取html
    html = get_html(code, start_date, end_date, page, per)
    soup = BeautifulSoup(html, 'html.parser')
    # 获取总页数
    pattern = re.compile('pages:(.*),')
    result = re.search(pattern, html).group(1)
    total_page = int(result)
    # 获取表头信息
    heads = []
    for head in soup.findAll("th"):
        heads.append(head.contents[0])

    # 数据存取列表
    records = []
    # 获取每一页的数据
    current_page = 1
    while current_page <= total_page:
        html = get_html(code, start_date, end_date, current_page, per)
        soup = BeautifulSoup(html, 'html.parser')
        # 获取数据
        for row in soup.findAll("tbody")[0].findAll("tr"):
            row_records = []
            for record in row.findAll('td'):
                val = record.contents
                # 处理空值
                if val == []:
                    row_records.append(np.nan)
                else:
                    row_records.append(val[0])
            # 记录数据
            records.append(row_records)
        # 下一页
        current_page = current_page + 1

    # 将数据转换为Dataframe对象
    np_records = np.array(records)
    fund_df = pd.DataFrame()
    for col, col_name in enumerate(heads):
        fund_df[col_name] = np_records[:, col]

    # 按照日期排序
    fund_df['净值日期'] = pd.to_datetime(fund_df['净值日期'], format='%Y/%m/%d')
    fund_df = fund_df.sort_values(by='净值日期', axis=0, ascending=True).reset_index(drop=True)
    fund_df = fund_df.set_index('净值日期')

    # 数据类型处理
    fund_df['单位净值'] = fund_df['单位净值'].astype(float)
    fund_df['累计净值'] = fund_df['累计净值'].astype(float)
    fund_df['日增长率'] = fund_df['日增长率'].str.strip('%').astype(float)
    return fund_df


def get_gsz(code):
    url = 'http://fundgz.1234567.com.cn/js/{}.js'.format(code)
    rsp = requests.get(url)
    html = rsp.text
    ls = json.loads(html[8:-2])
    return ls


def 投资建议(day, code):
    date = day
    end_date = pd.to_datetime(time.strftime("%Y-%m-%d", time.localtime(time.time())))
    start_date = end_date - pd.Timedelta(days=date)
    fund_df = get_fund(code, start_date=start_date, end_date=end_date)
    平均线 = fund_df.单位净值.mean()
    return 平均线


def 临时保存():
    global pdff
    today = time.strftime("%Y-%m-%d", time.localtime(time.time()))
    h5 = [x for x in os.listdir(base_dir) if os.path.isfile(x) and os.path.splitext(x)[1] == '.h5']
    if len(h5) == 0:
        topd_list = []
        for i in jj_list:
            ls_list = []
            ls = get_gsz(i)
            ls_list.append(ls['fundcode'])
            ls_list.append(ls['name'])
            ls_list.append(ls['dwjz'])
            ls_list.append(投资建议(30, i))
            ls_list.append(投资建议(60, i))
            ls_list.append(投资建议(90, i))
            topd_list.append(ls_list)
        pdff = pd.DataFrame(topd_list, columns=['基金代码', '基金名称', '前日净值', '30日均值', '60日均值', '90日均值'])
        pdff.to_hdf(today + '_jj.h5', 'obj1', format='table')
    else:
        for n in os.listdir(base_dir):
            if re.match('^\d{4}.\d{2}.\d{2}_jj.h5', n):
                if n == today + '_jj.h5':
                    pdff = pd.read_hdf(today + '_jj.h5', 'obj1')
                else:
                    os.remove(base_dir + "/" + n)
                    topd_list = []
                    for i in jj_list:
                        ls_list = []
                        ls = get_gsz(i)
                        ls_list.append(ls['fundcode'])
                        ls_list.append(ls['name'])
                        ls_list.append(ls['dwjz'])
                        ls_list.append(投资建议(30, i))
                        ls_list.append(投资建议(60, i))
                        ls_list.append(投资建议(90, i))
                        topd_list.append(ls_list)
                    pdff = pd.DataFrame(topd_list, columns=['基金代码', '基金名称', '前日净值', '30日均值', '60日均值', '90日均值'])
                    pdff.to_hdf(today + '_jj.h5', 'obj1', format='table')

    return pdff


jj_list = ['260108', '005454', '161024', '002079', '001879', '005043', '501058', '005969', '004813', '005940',
           '005928', '009068', '008641', '005353', '519772', '180012', '002621', '519674', '161903', '161725',
           '005176', '006229', '320007', '006253', '161726']


def run_app():
    topd_list = []
    for i in jj_list:
        ls_list = []
        ls = get_gsz(i)
        ls_list.append(ls['fundcode'])
        ls_list.append(ls['gsz'])
        topd_list.append(ls_list)
    pdf = pd.DataFrame(topd_list, columns=['基金代码', '实时估算值'])
    pdf2 = 临时保存()
    pdf = pd.merge(pdf2, pdf, how='left')
    pdf['实时估算值'] = pdf['实时估算值'].astype('float64')
    pdf['前日净值'] = pdf['前日净值'].astype('float64')
    pdf['实时收益率'] = (pdf['实时估算值'] - pdf['前日净值']) / pdf['前日净值']
    pdf['30日收益率'] = (pdf['实时估算值'] - pdf['30日均值']) / pdf['30日均值']
    pdf['60日收益率'] = (pdf['实时估算值'] - pdf['60日均值']) / pdf['60日均值']
    pdf['90日收益率'] = (pdf['实时估算值'] - pdf['90日均值']) / pdf['90日均值']
    pdf = pdf.sort_values(by='30日收益率')
    pdf['实时收益率'] = pdf['实时收益率'].map(lambda x: format(x, '.2%'))
    pdf['30日收益率'] = pdf['30日收益率'].map(lambda x: format(x, '.2%'))
    pdf['60日收益率'] = pdf['60日收益率'].map(lambda x: format(x, '.2%'))
    pdf['90日收益率'] = pdf['90日收益率'].map(lambda x: format(x, '.2%'))
    关注点 = {'基金代码': ['002621', '161024', '260108', '161725', '161726'],
           '关注点': [2.72, 1.1, 2, 1.15, 0.9]}
    gzd = pd.DataFrame(关注点)
    pdf = pd.merge(pdf, gzd, how='left')
    pdf.to_html(os.path.join(base_dir, 'templates', 'date.html'))


if __name__ == '__main__':
    print(run_app())
